package br.edu.ufcg.greengrid;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import br.edu.ufcg.greengrid.workload.BulkDataImpl;
import br.edu.ufcg.greengrid.workload.DGTAConverter;
import br.edu.ufcg.greengrid.workload.MachineAvailabilityComparator;
import br.edu.ufcg.greengrid.workload.PlainTextWorkloadParser;

import com.mallardsoft.tuple.Triple;

public class MainDGTAWorkloadParser {

	public static final String KEY_TRACE = "TRACE";

	public static final String UCB = "UCB";

	public static final String DEUG = "DEUG";

	public static void main(String[] args) throws IOException {

		if (args.length != 3) {
			System.err.println("Error! Usage: <trace name: UCB/DEUG> <outputFileName> <inputDirectory>");
			System.exit(1);
		}

		int index = 0;
		String trace = args[index++];
		String outputFileName = args[index++];
		File outputFile = new File(outputFileName);
		File directory = new File(args[index++]);

		if (!directory.exists()) {
			throw new IllegalArgumentException(String.format("Error! Directory does not exist: %s", directory
					.getAbsolutePath()));
		}

		if (!directory.isDirectory()) {
			throw new IllegalArgumentException(String.format("Error! Input directory is not a directory: %s", directory
					.getAbsolutePath()));
		}

		if (outputFile.exists()) {
			throw new IllegalArgumentException(String.format("Error! Output file already exists %s!", outputFile
					.getAbsolutePath()));
		}

		List<String> filesName = new LinkedList<String>();
		readFilesForDGTAWorkload(trace, directory, filesName);

		Comparator<Triple<String, Long, Long>> comparator = new MachineAvailabilityComparator();
		BulkDataImpl<Triple<String, Long, Long>> bulkData = new BulkDataImpl<Triple<String, Long, Long>>(comparator);
		DGTAConverter converter = new DGTAConverter(bulkData);
		PlainTextWorkloadParser parser = new PlainTextWorkloadParser(converter);
		parser.parse(filesName);
		parser.generateOutput(outputFile);

	}

	private static void readFilesForDGTAWorkload(String trace, File inputDirectory, List<String> filesName) {

		List<File> directories = new LinkedList<File>();
		for (File file : inputDirectory.listFiles()) {
			if (file.isDirectory()) {
				directories.add(file);
			}
		}

		Comparator<File> comparator = null;
		if (trace.equals(UCB)) {
			comparator = new Comparator<File>() {

				@Override
				public int compare(File f1, File f2) {

					String[] splitF1 = f1.getAbsolutePath().split("_");// <MONTH>_<DAY>_<YEAR>
					String[] splitF2 = f2.getAbsolutePath().split("_");// <MONTH>_<DAY>_<YEAR>

					for (int index = 0; index < 2; index++) {
						normalize(splitF1, index);
						normalize(splitF2, index);
					}

					return (join(splitF1, " ")).compareTo(join(splitF2, " "));
				}

				private void normalize(String[] split, int index) {

					if (split[index].length() == 1) {
						split[index] = "0" + split[index];
					}
				}
			};
		} else if (trace.equals(DEUG)) {
			comparator = new Comparator<File>() {

				@Override
				public int compare(File f1, File f2) {

					String[] splitF1 = f1.getAbsolutePath().split("[_-]");// <Month>-<Day>_<Month>-<Day>_<Year>
					String[] splitF2 = f2.getAbsolutePath().split("[_-]");// <Month>-<Day>_<Month>-<Day>_<Year>

					for (int index = 0; index < 4; index++) {
						normalize(splitF1, index);
						normalize(splitF2, index);
					}

					return (join(splitF1, " ")).compareTo(join(splitF2, " "));
				}

				private void normalize(String[] split, int index) {

					if (split[index].length() == 1) {
						split[index] = "0" + split[index];
					}
				}
			};
		} else {
			throw new IllegalArgumentException(String.format("Error! Unkown trace: %s", trace));
		}

		Collections.sort(directories, comparator);

		for (File file : directories) {

			for (File input : file.listFiles()) {
				filesName.add(input.getAbsolutePath());
			}

		}

	}

	private static String join(String[] split, String separator) {

		StringBuilder sb = new StringBuilder();
		String sep = "";

		for (int i = 0; i < split.length; i++) {
			sb.append(sep);
			sb.append(split[i]);
			sep = separator;
		}

		return sb.toString();
	}

}
